package com.hh.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.hh.demo.doc.CourseDoc;
import com.hh.demo.domain.*;
import com.hh.demo.dto.CourseDto;
import com.hh.demo.dto.MessageSmsDto;
import com.hh.demo.dto.UserSmsDto;
import com.hh.demo.feignClient.CourseSearchFeignClient;
import com.hh.demo.feignClient.MediaFileFeignClient;
import com.hh.demo.mapper.CourseMapper;
import com.hh.demo.mapper.TeacherMapper;
import com.hh.demo.result.JSONResult;
import com.hh.demo.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hh.demo.util.AssertUtil;
import com.hh.demo.util.StrUtils;
import com.hh.demo.vo.CourseDetailVo;
import com.hh.demo.vo.CourseItemVo;
import com.hh.demo.vo.CourserOrderVo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.hh.demo.constants.MqConstants.COURSE_SMS_TAG;
import static com.hh.demo.constants.MqConstants.COURSE_SMS_TOPIC;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author goeun
 * @since 2022-07-20
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Resource
    private ITeacherService teacherService;
    @Resource
    private ICourseDetailService courseDetailService;
    @Resource
    private ICourseMarketService courseMarketService;
    @Resource
    private ICourseTeacherService courseTeacherService;
    @Resource
    private ICourseTypeService courseTypeService;
    @Resource
    private ICourseSummaryService courseSummaryService;
    @Resource
    private ICourseResourceService courseResourceService;
    @Resource
    private CourseSearchFeignClient courseSearchFeignClient;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private TeacherMapper teacherMapper;
    @Resource
    private ICourseChapterService courseChapterService;
    @Resource
    private MediaFileFeignClient mediaFileFeignClient;

    @Override
    @Transactional
    public void mySave(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseResource courseResource = courseDto.getCourseResource();
        List<Long> teacherIds = courseDto.getTeacherIds();
        //课程不能被注册
        Course selectOne = selectOne(new EntityWrapper<Course>().eq("name", course.getName()));
        AssertUtil.isNull(selectOne,"该课程已被注册！");
        //保存课程
        course.setStatus(Course.STATE_OFFLINE);
        course.setLoginId(1L);
        course.setLoginUserName("yhptest1");
        List<Teacher> teachers = teacherService.selectBatchIds(teacherIds);
        String teacherNames = teachers.stream().map(Teacher::getName).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        //保存课程详情
        courseDetail.setId(course.getId());
        courseDetailService.insert(courseDetail);
        //保存课程market
        courseMarket.setId(course.getId());
        courseMarketService.insert(courseMarket);
        //保存课程讲师
        teacherIds.forEach(id->{
            CourseTeacher courseTeacher = new CourseTeacher();
            courseTeacher.setCourseId(course.getId());
            courseTeacher.setTeacherId(id);
            courseTeacherService.insert(courseTeacher);
        });
        //保存课程资源
        courseResource.setCourseId(course.getId());
        courseResourceService.insert(courseResource);
        //保存课程统计
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummaryService.insert(courseSummary);
        //课程类型表中的课程数+1
        CourseType type = courseTypeService.selectById(course.getCourseTypeId());
        type.setTotalCount(type.getTotalCount() + 1);
        courseTypeService.updateById(type);
    }

    @Override
    @Transactional
    public void onLineCourse(Long courseId) {
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course,"课程不能为空！");
        boolean offLine = course.getStatus() == Course.STATE_OFFLINE;
        AssertUtil.isTrue(offLine,"课程状态不满足");
        //修改状态为上架，增加上架时间
        course.setStatus(Course.STATE_ONLINE);
        course.setOnlineTime(new Date());
        updateById(course);
        //保存到es
        CourseType type = courseTypeService.selectById(course.getCourseTypeId());
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        CourseDoc doc = new CourseDoc();
        //设置需要保存到Es的字段
        BeanUtils.copyProperties(course,doc);
        BeanUtils.copyProperties(courseMarket,doc);
        BeanUtils.copyProperties(courseSummary,doc);
        doc.setCourseTypeName(type.getName());//这里要单独赋值
        String chargeName = courseMarket.getCharge() == 1 ? "免费" : "收费";
        doc.setChargeName(chargeName);

        JSONResult jsonResult = courseSearchFeignClient.saveCourse(doc);
        AssertUtil.isTrue(jsonResult.isSuccess(),"课程发布失败");
        //发送mq单向消息
        //rocketMQTemplate.sendOneWay("course-topic:course-tags","您好，课程《"+course.getName()+"》已上线，欢迎学习！");
        sendMessage(doc);
    }

    @Override
    @Transactional
    public void offLineCourse(Long courseId) {
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course,"课程不能为空！");
        boolean offLine = course.getStatus() == Course.STATE_ONLINE;
        AssertUtil.isTrue(offLine,"课程状态不满足");
        //修改状态为下架
        course.setStatus(Course.STATE_OFFLINE);
        updateById(course);
        //删除es里的数据
        JSONResult jsonResult = courseSearchFeignClient.deleteCourse(courseId);
        AssertUtil.isTrue(jsonResult.isSuccess(),"课程删除失败");
    }

    @Override
    public CourseDetailVo getCourseDetail(Long courseId) {
        AssertUtil.isNotNull(courseId,"请求非法");
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course,"请求非法");
        boolean onLine = course.getStatus() == Course.STATE_ONLINE;
        AssertUtil.isTrue(onLine,"请求非法");

        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        List<Teacher> teachers = teacherMapper.selectByCourseId(courseId);

        List<CourseChapter> courseChapters = courseChapterService.selectList(new EntityWrapper<CourseChapter>().eq("course_id", courseId));
        courseChapters.forEach(courseChapter -> {
            JSONResult jsonResult = mediaFileFeignClient.selectMediaFile(courseChapter.getId());
            if(jsonResult.isSuccess() && jsonResult.getData() != null){
                List<MediaFile> fileList = JSONObject.parseArray(jsonResult.getData().toString(), MediaFile.class);
                courseChapter.getMediaFiles().addAll(fileList);
            }
        });
        return new CourseDetailVo(courseMarket,course,courseChapters,teachers,courseSummary,courseDetail);
    }

    @Override
    public CourserOrderVo courserOrderVo(String courseIds) {
        List<Long> ids = StrUtils.splitStr2LongArr(courseIds);
        Set<Long> set = ids.stream().collect(Collectors.toSet());
        //判断id的个数，有没有传重复的课程id
        boolean flag = ids.size() == set.size();
        AssertUtil.isTrue(flag,"课程重复！");
        List<CourseItemVo> courseInfos = new ArrayList<>();
        BigDecimal totalAmount = new BigDecimal(0);
        for (Long id : set) {
            Course course = selectById(id);
            AssertUtil.isNotNull(course,"课程不存在！");
            boolean online = course.getStatus() == Course.STATE_ONLINE;
            AssertUtil.isTrue(online,"课程状态异常！");
            CourseMarket courseMarket = courseMarketService.selectById(id);
            AssertUtil.isNotNull(courseMarket,"课程不存在！");
            CourseItemVo courseItemVo = new CourseItemVo(course, courseMarket);
            courseInfos.add(courseItemVo);
            totalAmount = totalAmount.add(courseMarket.getPrice());
        }
        return new CourserOrderVo(courseInfos,totalAmount);
    }

    private void sendMessage(CourseDoc doc) {
        MessageSmsDto messageSmsDto = new MessageSmsDto();
        messageSmsDto.setTitle("新课程发布"+doc.getName());
        messageSmsDto.setContent("亲，您关注的"+
                doc.getCourseTypeName()+
                "相关的课程"+doc.getName()+
                "已上线，尝鲜地址：<a href='localhost:6002/list.html?coursId="+doc.getId()+"'");
        List<UserSmsDto> userSmsDtos = Arrays.asList(
                new UserSmsDto(1L, "13330964748"),
                new UserSmsDto(2L, "18000534099")
        );
        messageSmsDto.setUsers(userSmsDtos);
        rocketMQTemplate.sendOneWay(
                COURSE_SMS_TOPIC+":"+COURSE_SMS_TAG,
                JSON.toJSONString(messageSmsDto)
        );

    }
}
